#include "SH367309.h"
#include <rtthread.h>
#include <rtdevice.h>

static struct rt_i2c_bus_device *i2c_bus;

static rt_err_t read_register(rt_uint8_t reg_addr, rt_uint8_t *data, rt_size_t len)
{
    struct rt_i2c_msg msgs[2];
    rt_uint8_t send_buf[1];

    send_buf[0] = reg_addr;

    msgs[0].addr  = 0x40;  // SH367309 default I2C address
    msgs[0].flags = RT_I2C_WR;
    msgs[0].buf   = send_buf;
    msgs[0].len   = 1;

    msgs[1].addr  = 0x40;  // SH367309 default I2C address
    msgs[1].flags = RT_I2C_RD;
    msgs[1].buf   = data;
    msgs[1].len   = len;

    if (rt_i2c_transfer(i2c_bus, msgs, 2) != 2)
    {
        return RT_ERROR;
    }

    return RT_EOK;
}

void sh367309_init(void)
{
    // Initialize I2C bus
    i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(SH367309_I2C_DEVICE_NAME);
    if (!i2c_bus)
    {
        rt_kprintf("I2C device not found\n");
        return;
    }
}

rt_err_t sh367309_read_voltage(rt_uint16_t *voltage, rt_uint8_t cell_index)
{
    if (cell_index >= SH367309_NUM_CELLS)
    {
        return RT_ERROR;
    }

    rt_uint8_t reg_addr = SH367309_REG_VOLTAGE_CELL_BASE + cell_index * 2;
    rt_uint8_t data[2];

    if (read_register(reg_addr, data, 2) != RT_EOK)
    {
        return RT_ERROR;
    }

    *voltage = (data[0] << 8) | data[1];

    // Convert raw value to voltage (assuming 1 LSB = 0.001V)
    *voltage *= 0.001;

    return RT_EOK;
}

rt_err_t sh367309_read_all_voltages(rt_uint16_t voltages[SH367309_NUM_CELLS])
{
    for (rt_uint8_t i = 0; i < SH367309_NUM_CELLS; i++)
    {
        if (sh367309_read_voltage(&voltages[i], i) != RT_EOK)
        {
            return RT_ERROR;
        }
    }

    return RT_EOK;
}

rt_err_t sh367309_read_current(rt_int16_t *current)
{
    rt_uint8_t data[2];

    if (read_register(SH367309_REG_CURRENT, data, 2) != RT_EOK)
    {
        return RT_ERROR;
    }

    *current = (data[0] << 8) | data[1];

    // Convert raw value to current (assuming 1 LSB = 0.1mA)
    *current *= 0.1;

    return RT_EOK;
}

rt_err_t sh367309_read_temperature(rt_uint16_t *temperature, rt_uint8_t temperature_index)
{
    if (temperature_index >= SH367309_NUM_TEMPERATURES)
       {
           return RT_ERROR;
       }

       rt_uint8_t reg_addr = SH367309_REG_TEMPERATURE_BASE + temperature_index * 2;
       rt_uint8_t data[2];

       if (read_register(reg_addr, data, 2) != RT_EOK)
       {
           return RT_ERROR;
       }

       *temperature = (data[0] << 8) | data[1];

       // Convert raw value to voltage (assuming 1 LSB = 0.001V)
       *temperature *= 0.001;   //tbd

       return RT_EOK;
}

rt_err_t sh367309_read_all_temperatures(rt_uint16_t temperatures[SH367309_NUM_TEMPERATURES])
{
    for (rt_uint8_t i = 0; i < SH367309_NUM_TEMPERATURES; i++)
       {
           if (sh367309_read_temperature(&temperatures[i], i) != RT_EOK)
           {
               return RT_ERROR;
           }
       }
    return RT_EOK;
}
